package com.yayo.mangement.security.utils;

import com.alibaba.fastjson.JSON;
import com.yayo.mangement.info.UserInfo;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @JwtUtil: JWT工具包
 * @author: Yayo
 * @date: 2022/9/3 20:02
 */
@Slf4j
public class JwtUtil {

    public static final long EXPIRE = 1000 * 60 * 60 * 24;//token过期时间   24小时
    public static final long REFRESH = 1000 * 60 * 60; //token续约时间 1小时
    public static final String APP_SECRET = "Yayo";//密钥


    /**
     * 获取token
     * @param id
     * @param account
     * @return
     */
    public static String getToken(String id, String account){
        String token = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject("jacob-user")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
                .claim("id", id)
                .claim("account", account)
                .signWith(SignatureAlgorithm.HS256, APP_SECRET)
                .compact();
        return token;
    }

    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(1L);
        userInfo.setUserName("123");
        userInfo.setUserPic("");
        String token = getToken("1", JSON.toJSONString(userInfo));
        System.out.println(token);
    }

    /**
     * 判断token过期时间是否在一小时之内，默认token合法
     * @param request
     * @return
     */
    public static boolean checkExpInHour(HttpServletRequest request){
        String cookie = request.getHeader("Cookie");
        String token = cookie.replaceFirst("authorization=","");
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
        Claims claims = claimsJws.getBody();
        long expiration = Long.parseLong(claims.get("exp").toString()) * 1000;
        if((System.currentTimeMillis() + REFRESH) > expiration){
            return true;
        }
        return false;
    }

    /**
     * 根据token，判断token是否存在与有效
     * @param token
     * @return
     */
    public static boolean checkToken(String token) {
        if(StringUtils.isEmpty(token)) return false;
        try {
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
        } catch (Exception e) {
            log.error("token.error");
            return false;
        }
        return true;
    }

    /**
     * 根据request判断token是否存在与有效（也就是把token取出来罢了）
     * @param request
     * @return
     */
    public static boolean checkToken(HttpServletRequest request) {
        try {
            String cookie = request.getHeader("Cookie");
            if(cookie == null)
                return false;
            String token = cookie.replaceFirst("authorization=","");
            if(StringUtils.isEmpty(token))
                return false;
            Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("token.error");
            return false;
        }
        return true;
    }

    /**
     * 根据token获取会员id
     * @param request
     * @return
     */
    public static String getMemberIdByJwtToken(HttpServletRequest request) {
        String cookie = request.getHeader("Cookie");
        String token = cookie.replaceFirst("authorization=","");
        if(StringUtils.isEmpty(token)) return "";
        try {
            // 这里解析可能会抛异常，所以try catch来捕捉
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
            Claims claims = claimsJws.getBody();
            return claims.get("id", String.class);
        }catch (Exception e){
            log.error("token.error");
            return "";
        }
    }

    /**
     * 根据token获取会员id
     * @param request
     * @return
     */
    public static UserInfo getAccountByJwtToken(HttpServletRequest request) {
        String cookie = request.getHeader("Cookie");
        String token = cookie.replaceFirst("authorization=","");
        if(StringUtils.isEmpty(token))
            return null;
        try {
            return getMemberAccountByJwtToken(token);
        }catch (Exception e){
            log.error("token.error");
            return null;
        }
    }

    /**
     * 根据token获取用户的account
     * @param token
     * @return
     */
    public static UserInfo getMemberAccountByJwtToken(String token) {
        if(StringUtils.isEmpty(token))
            return null;
        try{
            Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(token);
            Claims claims = claimsJws.getBody();
            String account = claims.get("account",String.class);
            return JSON.parseObject(account, UserInfo.class);
        }catch (Exception e){
            log.error("token.error");
            return null;
        }
    }

}
